package com.yhxd.modular.news.service;

import com.querydsl.core.QueryResults;
import com.querydsl.core.types.ExpressionUtils;
import com.querydsl.core.types.OrderSpecifier;
import com.querydsl.core.types.Predicate;
import com.querydsl.jpa.impl.JPAQueryFactory;
import com.yhxd.modular.institutions.entity.Dept;
import com.yhxd.modular.institutions.entity.QDept;
import com.yhxd.modular.news.dao.AllInfoDao;
import com.yhxd.modular.news.dao.AttachmentDao;
import com.yhxd.modular.news.dao.MyInfoDao;
import com.yhxd.modular.news.entity.Attachment;
import com.yhxd.modular.news.entity.Classify;
import com.yhxd.modular.news.entity.News;
import com.yhxd.modular.news.entity.QNews;
import com.yhxd.modular.system.entity.User;
import com.yhxd.modular.system.vo.ResultVo;
import com.yhxd.utils.DateUtils;
import com.yhxd.utils.QueryDslUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.data.querydsl.QPageRequest;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.persistence.criteria.*;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Service
public class MyInformationService {

    @Autowired
    private JPAQueryFactory factory;

    @Autowired
    private MyInfoDao myInfoDao;

    @Autowired
    private AttachmentDao attachmentDao;

    /**
     * 分页查询权限列表
     * @param pageRequest
     * @return
     */
    public Page<News> findAll(QPageRequest pageRequest, News dto) {
        User shiroUser = (User) SecurityUtils.getSubject().getPrincipals().getPrimaryPrincipal();
        QNews qNews = QNews.news;
        QDept qDept = QDept.dept;

        Predicate where = qNews.id.isNotNull();
        if (ObjectUtils.isNotEmpty(dto.getTitle())){
            where = ExpressionUtils.and(where, qNews.title.like("%" + dto.getTitle() + "%"));
        }
        //信息大类
        Classify parentClassify = dto.getParentClassify();
        if (ObjectUtils.isNotEmpty(parentClassify) && ObjectUtils.isNotEmpty(parentClassify.getId())){
            where = ExpressionUtils.and(where, qNews.pcid.eq(dto.getParentClassify().getId()));
        }
        //信息小类
        Classify childClassify = dto.getChildClassify();
        if (ObjectUtils.isNotEmpty(childClassify) && ObjectUtils.isNotEmpty(childClassify.getId())){
            where = ExpressionUtils.and(where, qNews.ccid.eq(dto.getChildClassify().getId()));
        }
        //信息类型
        if (ObjectUtils.isNotEmpty(dto.getConType())){
            where = ExpressionUtils.and(where, qNews.conType.eq(dto.getConType()));
        }
        //信息状态
        if (ObjectUtils.isNotEmpty(dto.getStatus())){
            where = ExpressionUtils.and(where, qNews.status.eq(dto.getStatus()));
        }
        //发布时间
        if (ObjectUtils.isNotEmpty(dto.getPublishDate())){
            where = ExpressionUtils.and(where, qNews.publishDate.between(DateUtils.getTimesStart(dto.getPublishDate()),DateUtils.getTimesEnd(dto.getPublishDate())));
        }
        //有效期开始
        if (ObjectUtils.isNotEmpty(dto.getBeginDate())){
            where = ExpressionUtils.and(where, qNews.beginDate.isNull().or(qNews.beginDate.loe(DateUtils.getTimesStart(dto.getBeginDate()))));
        }
        //有效期结束
        if (null!=dto.getEndDate()) {
            where = ExpressionUtils.and(where, qNews.endDate.isNull().or(qNews.endDate.goe(DateUtils.getTimesStart(dto.getEndDate()))));
        }
        //部门
        Dept dept = dto.getDept();
        if (ObjectUtils.isNotEmpty(dept) && ObjectUtils.isNotEmpty(dept.getDepName())) {
            where = ExpressionUtils.and(where, qDept.depName.like("%" + dept.getDepName() + "%"));
        }
        where = ExpressionUtils.and(where, qNews.createName.eq(shiroUser.getRealName()));

        QueryResults<News> newsList = this.factory
                .selectFrom(qNews)
                .leftJoin(qDept)
                .on(qNews.deptId.eq(qDept.id))
                .where(where)
                .orderBy(QueryDslUtils.getOrderSpecifier(pageRequest.getSort()))
                .offset(pageRequest.getOffset())
                .limit(pageRequest.getPageSize())
                .fetchResults();
        Page<News> newsPage = new PageImpl<>(newsList.getResults(), pageRequest, newsList.getTotal());
        return newsPage;
    }


    /**
     * 按id删除数据
     * @param id
     */
    @Transactional(rollbackFor = Exception.class)
    public void deleteById(Long id) {
        QNews qNews = QNews.news;
        this.factory
                .delete(qNews)
                .where(qNews.id.eq(id))
                .execute();
    }
    //详情查询
    public News findById(Long id) {
        return this.myInfoDao.findById(id).orElse(null);
    }

    /**
     * 添加或修改新闻信息
     * @param news
     */
    @Transactional(rollbackFor = Exception.class)
    public ResultVo saveOrUpdate(News news) {
        User user = (User) SecurityUtils.getSubject().getPrincipals().getPrimaryPrincipal();
        Date date=new Date();
        if (null == news.getId()) {
            news.setCreateName(user.getRealName());
            news.setCreateTime(date);
            this.myInfoDao.save(news);
            //附件处理
            if(null!=news.getAttachmentList()){
                news.getAttachmentList().forEach(d->{
                    d.setCreateName(user.getRealName());
                    d.setCreateTime(new Date());
                    attachmentDao.save(d);
                });
            }
            return ResultVo.success(null);
        } else {
            News news1 = this.myInfoDao.findById(news.getId()).orElse(null);
            if(news1!=null){
                news1.setUpdateName(user.getRealName());
                news1.setUpdateTime(date);
                news1.setTitle(news.getTitle());
                news1.setConType(news.getConType());
                news1.setFilePath(news.getFilePath());
                news1.setContent(news.getContent());
                news1.setBeginDate(news.getBeginDate());
                news1.setEndDate(news.getEndDate());
                this.myInfoDao.save(news1);
                //附件处理
                if(null!=news.getAttachmentList()){
                    //先删除再插入
                    if(null!=news1.getAttachmentList()){
                        attachmentDao.deleteAll(news1.getAttachmentList());
                    }
                    news.getAttachmentList().forEach(d->{
                        d.setCreateName(user.getRealName());
                        d.setCreateTime(new Date());
                        attachmentDao.save(d);
                    });
                }
                return ResultVo.success(null);
            }else{
                return ResultVo.error("修改部门不存在");
            }
        }
    }

    /**
     * 消息发布
     * @param id
     */
    @Transactional(rollbackFor = Exception.class)
    public ResultVo release(Long id) throws Exception {
        User user = (User) SecurityUtils.getSubject().getPrincipals().getPrimaryPrincipal();
        Date date=new Date();
        News news = this.myInfoDao.findById(id).orElse(null);
        if(news!=null && news.getStatus()!=1){
            news.setStatus(1); //状态，0新建，1发布，2撤销，3删除
            news.setPublishName(user.getRealName());
            news.setPublishDate(date);
            myInfoDao.save(news);
            return ResultVo.success(null);
        }else{
            throw new Exception("该条发布数据不存在或已发布");
        }
    }
}
